package com.dragon.refect.classload;

import java.lang.reflect.Method;

/**
 * 类加载委托模型的好处
 * 1. 可以确保java的核心库的安全，所有的java应用都至少会引用java.lang.Object类，也就是在程序运行期间，java.lang.Object这个类
 * 会被加载到JVM虚拟机中;如果这个加载的过程是由Java应用自己的类加载器去完成，也就是说有可能会在JVM中存在多个版本的java.lang.Object类，
 * 而且这些类之间还是不兼容的，相互不可见的(正是命名空间在发挥这作用)。
 * 借助双亲委托机制，Java核心库中的类的加载工作都是由启动类加载器去统一完成的，从而确保了Java应用中所使用的都是同一个版本的Java核心类库，
 * 他们之间都是相互兼容的。
 * 2.可以确定Java核心库所提供的类不会被自定义的类所替代。
 * 3.不同的类加载器可以为相同的名称(binary name)的类创建额外的命名空间。相同名称的类可以并存在Java虚拟机中，只需要用不同的
 * 类加载器来加载他们即可。不同类加载器所加载的类之间是不兼容的，这就相当于在Java虚拟机内部创建了一个又一个相互隔离的Java类空间，
 * 这类技术在很多框架中得到了实际应用。
 *
 * @author dragon
 * @since 2019/11/22
 */
public class MyTest11 {

    public static void main(String[] args) throws Exception{
        MyClassLoader classloader1 = new MyClassLoader("classloader1");
        MyClassLoader classloader2 = new MyClassLoader("classloader2");

        classloader1.setPath("/Users/panlong/Downloads");
        classloader1.setPath("/Users/panlong/Downloads");

        Class<?> clazz1 = classloader1.loadClass("com.dragon.refect.classload.MyPerson");
        Class<?> clazz2 = classloader2.loadClass("com.dragon.refect.classload.MyPerson");

        System.out.println(clazz1 == clazz2);

        Object obj1 = clazz1.newInstance();
        Object obj2 = clazz2.newInstance();

        Method method = clazz1.getMethod("setMyPerson", Object.class);
        method.invoke(obj1, obj2);
    }
}
